package org.fjsei.yewu.service.third;

import com.alibaba.fastjson2.JSON;
import com.querydsl.core.BooleanBuilder;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import lombok.extern.slf4j.Slf4j;
import md.cm.base.Company;
import md.cm.geography.*;
import md.cm.unit.Division;
import md.cm.unit.DivisionRepository;
import md.cm.unit.Unit;
import md.specialEqp.*;
import md.specialEqp.inspect.Isp;
import md.specialEqp.inspect.IspRepository;
import md.specialEqp.type.*;
import md.system.User;
import org.fjsei.yewu.entity.fjtj.*;
import org.fjsei.yewu.entity.incp.*;
import org.fjsei.yewu.pojo.SliceSyncRes;
import org.fjsei.yewu.pojo.jsn.*;
import org.fjsei.yewu.repository.StoreSync;
import org.fjsei.yewu.repository.StoreSyncRepository;
import org.fjsei.yewu.repository.maint.JsliceMang;
import org.fjsei.yewu.resolver.MaintComn;
import org.fjsei.yewu.util.Tool;
import org.jgroups.util.Triple;
import org.jgroups.util.Tuple;
import org.quartz.JobKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.util.*;

import static graphql.Assert.assertNotNull;
import static graphql.Assert.assertTrue;
import static org.fjsei.yewu.util.Tool.*;

/**
 * 维护向导部分的，拆分功能到父类
 * 【迁移包】因为需避免class HouseBuilding {}这样的转换类产生太多的.java小文件个数；所以聚合方式内calss,最后导致本类需要被集成到当前可访问package包中,无需public访问HouseBuilding模式。
*/
@Slf4j
public class InfRecvConvert extends MaintComn {
    //@PersistenceContext(unitName = "entityManagerFactorySei")
    //private EntityManager emSei;                //EntityManager相当于hibernate.Session：
    @PersistenceContext(unitName = "entityManagerFactoryFjtj")
    protected EntityManager emFjtj;

    @Autowired
    protected DictAreaRepository dictAreaRepository;
    @Autowired
    MyRestServiceClient zhjyInf;
    @Autowired  protected ElasticsearchOperations esTemplate;
    @Autowired  protected JcPermtUntRepository jcPermtUntRepository;
    //@Autowired  private Units units;
    @Autowired  protected UntMgeRepository untMgeRepository;
    @Autowired  protected JcUntMgeRepository jcUntMgeRepository;
    @Autowired private HouseMgeRepository houseMgeRepository;
    @Autowired
    protected StoreSyncRepository storeSyncRepository;
    @Autowired protected UntDeptRepository untDeptRepository;
    @Autowired protected UntSecudeptRepository untSecudeptRepository;
    @Autowired protected HrDeptinfoRepository  hrDeptinfoRepository;
    @Autowired protected Equipments eQPRepository;
    @Autowired protected AdminunitRepository adminunitRepository;
    @Autowired protected VillageRepository villageRepository;
    @Autowired protected DivisionRepository divisionRepository;
    @Autowired  protected IspRepository iSPRepository;
    @Autowired protected JispUnitRepository jispUnitRepository;
    @Autowired protected PipeLineUnitRepository pipeLineUnitRepository;

    /**导来区划整个表
     * */
    public Boolean syncUnitFromLeg_AD第一步(String type) {
        if(!emFjtj.isJoinedToTransaction())      emFjtj.joinTransaction();
        Assert.isTrue(emFjtj.isJoinedToTransaction(),"没emFjtj Transaction");
        InfRespond<AreaCodName> recv=zhjyInf.get地区区域();
        List<AreaCodName> allrs=recv.getData();
        log.info("syncEqpFromOld:type={},条数{}",type, allrs.size() );
        int seq=1;
        int lopct=0;
        List<DictArea> batch=new ArrayList<>();
        for (AreaCodName one: allrs)
        {
            DictArea obj=DictArea.builder().FAU_TYPE_PARENT_CODE(one.getParentAreaCod()).FAU_TYPE_NAME(one.getAreaName())
                    .FAU_TYPE_CODE(one.getAreaCod()).FAU_TYPE_DETAIL(one.getIsDefault())
                    .id(String.valueOf(seq++)).build();
            lopct++;
            batch.add(obj);
            if(lopct>=800) {
                dictAreaRepository.saveAll(batch);
                lopct=0;
                batch.clear();
            }
        }
        dictAreaRepository.saveAll(batch);
        log.info("syncEqpFromOld:完成，type={},条数{}",type, seq);
        return true;
    }
    /**导楼盘小区导进到 临时过渡的fjtj数据库
     * */
    public Boolean syncUnitFromLeg_AD导楼盘小区() {
        if(!emFjtj.isJoinedToTransaction())      emFjtj.joinTransaction();
        Assert.isTrue(emFjtj.isJoinedToTransaction(),"没emFjtj");
        InfRespond<HouseBuilding> recv=zhjyInf.get楼盘名();
        List<HouseBuilding> allrs=recv.getRows();
        log.info("导楼盘小区:条数{},", allrs.size());
        int lopct=0;
        List<HouseMge> batch=new ArrayList<>();
        for (HouseBuilding one: allrs)
        {
            HouseMge obj=HouseMge.builder().id(one.getBuildId()).BUILD_NAME(one.getBuildName()).BUILD_ADDR(one.getBuildAddr())
                    .INST_BUILD_TYPE(one.getInstBuildType()).AREA_COD(one.getAreaCod()).BUILD_STATE(one.getMemo())
                    .build();
            lopct++;
            batch.add(obj);
            if(lopct>=800) {
                houseMgeRepository.saveAll(batch);
                lopct=0;
                batch.clear();
            }
        }
        houseMgeRepository.saveAll(batch);
        log.info("导楼盘小区-fjtj:Fin 条数{}", allrs.size());
        return true;
    }
    //value = "transactionManager",transactionManager="transactionManager", rollbackFor=Exception.class,
    @Transactional(timeout=60)
    public void syncEqpFromLegacy_AKinner(InfRespond<EqpCodOidno> recv){
        int countall=recv.getRows().size();
        int lopct=0;
        List<StoreSync> batch=new ArrayList<>();
        log.info("syncEqpFromLegacy_AK:inf{}",countall);
        for(int i =0; i<countall; i++)
        {
            EqpCodOidno one=recv.getRows().get(i);
            lopct++;
            StoreSync ado=StoreSync.builder().id(UUID.randomUUID()).oldId(one.getId()).cod(one.getEqpCod()).oid(one.getOidno()).amrServer(one.getAmrServer())
                    .eqpType(one.getEqpType()).eqpVart(one.getEqpVart()).eqpSort(one.getEqpSort()).subEqpVart(one.getSubEqpVart())
                    .build();
            batch.add(ado);
            if(lopct>=50) {
                //为何这里比 saveAll  更快？ .upsertAll(batch);
                storeSyncRepository.saveAll(batch);
                lopct=0;
                batch.clear();
            }
        }
        //原本非quatz情形是可以用.upsertAll(batch); [ERROR: cannot execute UPSERT in a read-only transaction] [n/a]
        storeSyncRepository.saveAll(batch);
        log.info("syncEqpFromLegacy_AK:commit{}", countall);
    }
    /**设备列表：cod="",oid=QH07421,邵武市的竟然是江西来检验！'中国铁路南昌局集团有限公司特种设备检测检验所'铁路系统特种设备作业人员培训;
     * 【注意】必须先手动清空storesync实体表 truncate table storesync; 避免重复。
     * 报错：ERROR: cannot execute UPSERT in a read-only transaction] [n/a]
     * */
    public Boolean syncEqpFromLegacy_AK(Long pageno, int pagesize) {
//        log.info("syncAK:begin page={},pagesize={}",pageno,pagesize);
        InfRespond<EqpCodOidno>  recv=null;
        int page= Math.toIntExact(pageno);         //对方实际?&page>=0的基数吗
        
//        recv=zhjyInf.getDeviceNos(page,pagesize);
//        syncEqpFromLegacy_AKinner(recv);
        log.info("syncAK:useing page={}, l={}",pageno,page);

       return true;
    }
    public Boolean syncEqpFromLegacy_AU(JsliceMang jobm, String arg) {
        if("Jy".equals(arg))  return syncFromLegacy_AU检验整Jy(jobm,arg);
        else if("Pu".equals(arg))  return syncFromLegacy_AU管道单元(jobm,arg);
        return true;
    }
    /**单位表不再获取监察的原始表了，优先采信检验平台的，不再考虑有关联监察平台的单位id。
     * */
    public Boolean syncFromLegacy_AU检验整Jy(JsliceMang jobm, String arg) {
        //没添加joinTransaction就不会保存数据库的。
        if(!emFjtj.isJoinedToTransaction())      emFjtj.joinTransaction();
        int pagesize=2000;
        log.info("syncEqpFromLegacy_AK: 开始 offset={}",jobm.getOffs());
        InfRespond<OldPtUnit>  recv=null;
        if(jobm.getOffs() >jobm.getTotl()) {
            jobm.setDesc("无法前进offset超过totl");    //默认jobm.getLimt()==1 数据库也必须配置=1
            return false;
        }
        int page=jobm.getOffs();    //实体要配置limt:=1; offs=1开始的;  totl>=sum/pagesize;
        recv=zhjyInf.get单位表(page,pagesize);
        List<OldPtUnit> allrs=recv.getRows();
        log.info("syncEqpFromLegacy_AK: sum={}", allrs.size());
        int countall=recv.getRows().size();
        int lopct=0;
        //List<String> fields=List.of("id","UNT_NAME","UNT_ORG_COD","ECONM_TYPE_COD","INDUSTRY_PROP_COD","UNT_PROP_COD","UNT_AREA_COD","UNT_ADDR","POST_COD",
        //     "UNT_LKMEN","UNT_MOBILE","LEADER","LEADER_PHONE","UNT_STATE","UNT_LAT","UNT_LONG","untTypesJson");
        List<UntMge> batch=new ArrayList<>();
        log.info("syncEqpFromLegacy_AK: 接口完count={}",countall);
        for (OldPtUnit one: allrs)
        {
            UntMge obj=UntMge.builder().id(one.getUntId()).UNT_NAME(one.getUntName()).UNT_ORG_COD(one.getUntOrgCod()).ECONM_TYPE_COD(one.getEconmTypeCod())
                    .INDUSTRY_PROP_COD(one.getIndustryPropCod()).UNT_PROP_COD(one.getUntPropCod()).UNT_AREA_COD(one.getUntAreaCod()).UNT_ADDR(one.getUntAddr())
                    .POST_COD(one.getPostCod()).UNT_LKMEN(one.getUntLkmen()).UNT_MOBILE(one.getUntMobile()).LEADER(one.getLeader()).LEADER_PHONE(one.getLeaderPhone())
                    .UNT_STATE(one.getUntState()).UNT_LAT(one.getUntLat()).UNT_LONG(one.getUntLong()).UNT_PHONE(one.getUntPhone())
                                    //.untTypesJson(one.getUntTypes().toString())
                    .build();
            Long[] jsonts= one.getUntTypes().toArray(new Long[0]);
            obj.setUntTypes(jsonts);
            batch.add(obj);
            lopct++;
            //一次性命令，保存个数太多了，反而性能更差！适度调节个数参数。【多数情况】saveAll比upsertAll性能更佳！
            if(lopct>30) {
                untMgeRepository.saveAll(batch);  // upsertAll   saveAll
                lopct=0;
                batch.clear();
            }
        }
        untMgeRepository.saveAll(batch);
//        untMgeRepository.upsertAll(batch);
        log.info("syncEqpFromLegacy_AK:完成！offs={},条数{}接着等数据库后台提交",jobm.getOffs(), countall);
        jobm.setOffs(jobm.getOffs()+1);
        if(countall < pagesize) {
            jobm.setDesc("无法前进offset");
            return false;
        }
        return true;
    }
    public <T> Triple makeInf使用单位部门(T inObj) {
        Company iden= (Company) inObj;
        if(!StringUtils.hasText(iden.getName()) || null==iden.getUnit())  return new Triple("", null, null);
        QUntMge qm = QUntMge.untMge;
        BooleanBuilder builder = new BooleanBuilder();
        builder.and(qm.uunit.eq(iden.getUnit().getId()));
        Iterable<UntMge> list = untMgeRepository.findAll(builder);
        Long olduID=null;
        for(UntMge item : list) {
            if(1!=item.getUNT_STATE() && null==olduID)
                olduID=item.getId();            //多个单位同名 被忽视
            else if(1==item.getUNT_STATE())
                olduID=item.getId();
        }
        if(null==olduID)   return new Triple("没旧untId", null, null);
        InfRespond<OldDepartment>  recv=zhjyInf.get使用单位部门(olduID);
        List<OldDepartment> allrs=recv.getRows();
        List<UntDept> batch=new ArrayList<>();
        log.info("makeInf使用单位部门: {},count={}",iden.getName(),allrs.size());
        int lopct=0;
        for (OldDepartment one: allrs)
        {
            UntDept obj=UntDept.builder().id(one.getUntDeptId()).name(one.getName()).DEPT_ADDR(one.getDeptAddr()).DEPT_AREA_COD(one.getDeptAreaCod())
                    .LKMEN(one.getLkmen()).PHONE(one.getPhone()).MOBILE(one.getMobile()).untId(one.getUntId())
                    .build();
            batch.add(obj);
            lopct++;
            if(lopct>30) {
                untDeptRepository.saveAll(batch);
                lopct=0;
                batch.clear();
            }
        }
        untDeptRepository.saveAll(batch);
        return new Triple("", null, null);
    }
    public <T> Triple makeInf使用单位机构分支(T inObj) {
        Company iden= (Company) inObj;
        if(!StringUtils.hasText(iden.getName()) || null==iden.getUnit())  return new Triple("", null, null);
        QUntMge qm = QUntMge.untMge;
        BooleanBuilder builder = new BooleanBuilder();
        builder.and(qm.uunit.eq(iden.getUnit().getId()));
        Iterable<UntMge> list = untMgeRepository.findAll(builder);
        Long olduID=null;
        for(UntMge item : list) {
            if(1!=item.getUNT_STATE() && null==olduID)
                olduID=item.getId();            //多个单位同名 被忽视
            else if(1==item.getUNT_STATE())
                olduID=item.getId();
        }
        if(null==olduID)   return new Triple("没旧untId", null, null);
        InfRespond<OldSecudept>  recv=zhjyInf.get使用单位机构分支(olduID);      //有可能接口长时间没有应答导致数据库事务的长时间运作？
        List<OldSecudept> allrs=recv.getRows();
        List<UntSecudept> batch=new ArrayList<>();
        log.info("makeInf使单位机构分支: {},count={}",iden.getName(),allrs.size());
        int lopct=0;
        for (OldSecudept one: allrs)
        {
            UntSecudept obj=UntSecudept.builder().id(one.getUntSecudeptId()).name(one.getName()).SECUDEPT_ADDR(one.getSecudeptAddr()).SECUDEPT_AREA_COD(one.getSecudeptAreaCod())
                    .LKMEN(one.getLkmen()).PHONE(one.getPhone()).MOBILE(one.getMobile()).UNT_ID(one.getUntId())
                    .build();
            batch.add(obj);
            lopct++;
            if(lopct>30) {
                untSecudeptRepository.saveAll(batch);
                lopct=0;
                batch.clear();
            }
        }
        untSecudeptRepository.saveAll(batch);
        return new Triple("", null, null);
    }
    public Boolean setupFromLegacy_DP检验HR部门(String arg) {
        if(!emFjtj.isJoinedToTransaction())     emFjtj.joinTransaction();
        System.out.println("设备检验HR部门开始：" +new Date());
        InfRespond<JianyanDepOffice>  recv=zhjyInf.get检验机构部门科室("dsf");      //有可能接口长时间没有应答导致数据库事务的长时间运作？
        List<JianyanDepOffice> allrs=recv.getData();
        log.info("Inf检验HR部门: 条数{}", allrs.size());
        int lopct=0, sumdep=0, sumofi=0;
        List<HrDeptinfo> batch=new ArrayList<>();
        for (JianyanDepOffice one: allrs)
        {
            HrDeptinfo obj=HrDeptinfo.builder().id(one.getId()).DEPT_NAME(one.getLabel()).status(one.getStatus()).DEPT_PRINC(one.getDeptPrinc()).deptLevel(one.getDeptLevel())
                    .parentId(null).build();
            batch.add(obj);
            lopct++;
            sumdep++;
            if(null!=one.getChildren()){
                for (DepNestOffice sono: one.getChildren())
                {
                    obj=HrDeptinfo.builder().id(sono.getId()).DEPT_NAME(sono.getLabel()).status(sono.getStatus()).DEPT_PRINC(sono.getDeptPrinc()).deptLevel(sono.getDeptLevel())
                            .parentId(one.getId()).build();
                    batch.add(obj);
                    lopct++;
                    sumofi++;
                }
            }
            if(lopct>30) {
                hrDeptinfoRepository.saveAll(batch);
                lopct=0;
                batch.clear();
            }
        }
        hrDeptinfoRepository.saveAll(batch);
        log.info("还原特检院部门:完成， dep数{} office={}",sumdep,sumofi);
        return true;
    }
    /**从旧平台获取某个设备信息+参数；
     * */
    public String getDeviceFromOld(JobKey jobKey,StoreSync ssinf, Unit ispUnit) throws InterruptedException {
        log.info("{}通道，正在处理设备cod={}",jobKey.getName(),ssinf.getCod());
        DataRespond<OldDeviceSkel<?>> recv=null;
        if("3000".equals(ssinf.getEqpType())){
            recv=(DataRespond)(zhjyInf.getDeviceParamElv(ssinf.getOldId()));
        }
        else if("2000".equals(ssinf.getEqpType())){
            recv=(DataRespond)zhjyInf.getDeviceParamVes(ssinf.getOldId());
        }
        else if("R000".equals(ssinf.getEqpType())){
            recv=(DataRespond)zhjyInf.getDeviceParamNpvs(ssinf.getOldId());
        }
        else if("4800".equals(ssinf.getEqpType())){
            recv=(DataRespond)zhjyInf.getDeviceParamLift(ssinf.getOldId());
        }
        else if("4000".equals(ssinf.getEqpType())){
            recv=(DataRespond)zhjyInf.getDeviceParamCra(ssinf.getOldId());
        }
        else if("1000".equals(ssinf.getEqpType())){
            recv=(DataRespond)zhjyInf.getDeviceParamBoil(ssinf.getOldId());
        }
        else if("5000".equals(ssinf.getEqpType())){
            recv=(DataRespond)zhjyInf.getDeviceParamCar(ssinf.getOldId());
        }
        else if("6000".equals(ssinf.getEqpType())){
            recv=(DataRespond)zhjyInf.getDeviceParamAmus(ssinf.getOldId());
        }
        else if("8000".equals(ssinf.getEqpType())){
            //为何id=898321 获取报500错
            recv=(DataRespond)zhjyInf.getDeviceParamPpin(ssinf.getOldId());
        }
        else {
            return ("9000".equals(ssinf.getEqpType()) ? "设备类暂弃" : "设备类无"+ssinf.getEqpType());
        }
        OldDeviceSkel dto=recv.getData();
        if(null==dto){
            //assertNotNull(dto, () -> "空dto");
            return "Inf空Dto";
        }
        //有涉及到事务数据库的部分：
        doSyncParmFromOld(ssinf,dto,ispUnit);
        return "";
    }
////返回异常消息:输入oid/cod,jc/jy,jcp/jyp 这3组合必须最少有一个数据。
//    /**基础信息：监察中有的字段监察优先； 关键技术字段是监察优先；其它技术参数是检验优先。
//     * 若oid<>'' oid+svu{JCUNT_ID盖过REG_UNT_ID默认福建省地市局};oid为空的看ispu{默认/地区}+cod作为搜索定位。
//     * 极度例外只有OIDNO其它全空但是有EQP_AREA_COD+EQP_USECERT_COD。
//     * */
    @Transactional(value = "transactionManager",transactionManager="transactionManager", rollbackFor=Exception.class, timeout=30)
    public StoreSync doSyncParmFromOld(StoreSync ssi,OldDeviceSkel ods, Unit ispu) throws InterruptedException {
        String res=doSyncParmFromOldInner(ssi,ods,ispu);
        if(StringUtils.hasText(res) ) ssi.setFail(res);
        else ssi.setFail("OK");
       return storeSyncRepository.save(ssi);
    }
    public String doSyncParmFromOldInner(StoreSync ssi,OldDeviceSkel ods, Unit ispu) throws InterruptedException {
//   User user=checkAuth();   if(null==user)  return null;
//        for(int i=0; i<=30; i++){
//            log.info("busy cct 第{}次", i);
//            Thread.sleep(2000); // Job takes 30 second to complete
//        }
        String retRes="";
        String oid=ods.getOidno(), cod=ods.getEqpCod();
        Eqp eqp=null;
        Unit svu=null;
        //首先必须决定svu,ispu两个单位。 应当归属监察机构svu：
        Long desId=null;  //福建省局: 监察平台的id和检验平台的id一样吗？监察JCUNT_ID: "1"
        svu= getUnitfromOldUnitId(false, ods.getRegUntId());
        assertNotNull(ispu, () -> "ispu空");
        if(null!=svu && StringUtils.hasText(oid)){
            //从数据库找到现成的Eqp:(oid,svu)都要配对。
            eqp = eQPRepository.findByOidAndSvu(oid, svu);  //找出多个设备=抛出异常!分片作业停止了;
        }
        if(null==eqp && StringUtils.hasText(cod)){
            //从数据库找到现成的Eqp:(cod,ispu)都要配对。
            eqp= eQPRepository.findByCodAndIspu(cod,ispu);
        }
//      else  return "无码查:"+oid+":"+cod;
        String type="", sort="", vart="";    //最少提前获知字段：
        //新 需要导入的设备
        if(null==eqp){
            //只能新生成个Eqp:
            eqp=new Eqp();
            if(!StringUtils.hasText(ods.getEqpType()))   return "EQP_TYPE空";
            type=ods.getEqpType().substring(0,1);
            Eqp.EqpBuilder<?, ?>  eqpBld=null;
            if(type.equals("3"))
                eqpBld = Elevator.builder();
            else if(type.equals("2") || type.equals("R"))
                eqpBld = Vessel.builder();
            else if(type.equals("1"))
                eqpBld = Boiler.builder();
            else if(type.equals("4"))
                eqpBld = Crane.builder();
            else if(type.equals("5"))
                eqpBld = FactoryVehicle.builder();
            else if(type.equals("6"))
                eqpBld = Amusement.builder();
            else if(type.equals("8"))
                eqpBld = Pipeline.builder();
            else if(type.equals("9"))
                eqpBld = Ropeway.builder();
            else
                eqpBld = Eqp.builder();
            if(StringUtils.hasText(ods.getEqpSort()))   sort=ods.getEqpSort().substring(0,2);
            if(StringUtils.hasText(ods.getEqpVart()))   vart=ods.getEqpVart().substring(0,3);
            //svu ispu 初始化后若修改 oid->要改svu, cod->要改动ispu需要删除旧的数据啊：不然重复的oid, cod！本平台允许oid cod对于正常逻辑允许重复，同步外部数据要例外处置。
            eqp =eqpBld.type(type).oid(oid).cod(cod).svu(svu).ispu(ispu).sort(sort).vart(vart)
                    .reg(RegState_Enum.values()[Integer.parseInt(ods.getEqpRegSta())]).ust(UseState_Enum.values()[Integer.parseInt(ods.getEqpUseSta())])
                    .build();
            try {
                eQPRepository.save(eqp);        //saveAndFlush
            } catch (Exception e) {
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return "flush败";
            }
        }
        else{       //已经存在设备， 不能修改svu ispu了，除非先删除掉，同步外部数据局限。
                eqp.setCod(cod);
                eqp.setOid(oid);     //[同步旧平台数据] oid不能从有的变身空的:后退
        }
        type=eqp.getType();
        sort=eqp.getSort();
        Tuple retv=fillEqpBase(eqp, ods,ispu);      //非新设备极个别字段oid cod svu ispu不能修改的。
        retRes+= retv.getVal1();
        eqp= (Eqp) retv.getVal2();
        retv=null;
        if("3000".equals(ssi.getEqpType())){
            retv= fillElevator((Elevator)eqp,ods);
        }
        else if("2000".equals(ssi.getEqpType())){
            retv= fillVessel((Vessel)eqp, ods);
        }
        else if("R000".equals(ssi.getEqpType())){
            retv= fillVessel常((Vessel)eqp, ods);
        }
        else if("4800".equals(ssi.getEqpType())){
            retv= fillCrane升降机((Crane)eqp,ods);
        }
        else if("4000".equals(ssi.getEqpType())){
            retv= fillCrane((Crane)eqp,ods);
        }
        else if("1000".equals(ssi.getEqpType())){
            retv= fillBoiler((Boiler)eqp,ods);
        }
        else if("5000".equals(ssi.getEqpType())){
            retv= fillFactoryVehicle((FactoryVehicle)eqp,ods);
        }
        else if("6000".equals(ssi.getEqpType())){
            retv= fillAmusement((Amusement)eqp,ods);
        }
        else if("8000".equals(ssi.getEqpType())){
            retv= fillPipeline((Pipeline)eqp,ods);
            //            if(eqp.getReg()!=RegState_Enum.CANCEL) {     //不一致，无法决定该采信JC还是JY，？监察平台优先:
            //                if (StringUtils.hasText(eqp.getOid())) {     //过滤后注册登记码是唯一的||空的；
            //                    conds = "OIDNO='" + eqp.getOid() + "' AND USE_STA<>7 AND USE_STA<>8 AND USE_STA<>5 AND USE_STA<>4";
            //                }
            //                if (StringUtils.hasText(eqp.getCod())) {      //两个平台看见的单元数和状态有很多不一致的，合并后会更多条数！
            //                    conds = "EQP_COD='" + eqp.getCod() + "' AND USE_STA<>7 AND USE_STA<>8 AND USE_STA<>5 AND USE_STA<>4";
            //                }
            //                retv = syncPipeDevice((Pipeline) eqp, jcls.getArr(), jyls.getArr());
            //            }
        }
        if(null!=retv){
            retRes+= retv.getVal1();   //返回值数组包装【错误信息，变更的设备Eqp】
            eqp= (Eqp) retv.getVal2();    //eqp可是出现变化的。eqp
        }
        //return("9000".equals(bigetly.getEqpType()) ? "设备类暂弃" : "设备类无"+bigetly.getEqpType());
        //这个时间eqp.isp1.id==eqp.isp2.id就会报错！同一个会话中后面new Isp()覆盖前面的isp1。
        eQPRepository.save(eqp);
        return retRes;   //为何退出时刻能够自动保存Eqp的修改。？？
    }
//    /**极个别字段oid cod svu ispu不能修改;复制基本台账信息, 各设备种类都用的参数；扣除最基础几个字段(分支条件)。
//     * 返回Tuple是两个数据合体的{resultStr 错误信息, eqp 本体ref由于build变动后}。
//     * 旧检验平台没有CERT_*4个字段=必须用监察的数据CERT_DATE 发证日期,CERT_EFF_DATE 证书有效期,CERT_STATUS 证书状态,FIRSTCERT_DATE 首次发证日期。
//     * */
    public Tuple fillEqpBase(Eqp eqp, OldDeviceSkel bsd,Unit ispu) {
        boolean usjc=false;
        String retRes = "";
//        Bigetly bsd=usjc? jc: jy;   //确保!null
        Assert.isTrue(eqp != null,"未找到eQP");
        Eqp.EqpBuilder<?, ?>  eqpBld=eqp.toBuilder();
        DeviceComnSvp svp=new DeviceComnSvp();    //各设备种类都有的svp,pa参数
        DeviceComnPam pam=new DeviceComnPam();
        Unit 设计单位=getUnitfromOldUnitId(usjc, bsd.getDesignUntId());
        Unit 型试单位=getUnitfromOldUnitId(usjc, bsd.getTestUntId());
//        Unit 造监检单=getUnitfromOldUnitId(usjc, bsd.getMakeIspUntId());
        //svp pa 两个特殊：可修改地方多。
        svp= svp.toBuilder().年限(bsd.getDesignUseYear()).重监控("1".equals(bsd.getIfMajctl()) || "是".equals(bsd.getIfMajctl()) )
                .制造国(bsd.getMakeCountry()).大修周期(String2Int(bsd.getAltCycle())).维周期(String2Int(bsd.getMantCycle()))
                .设计日期(bsd.getDesignDate())
//                .造监检单(null!=造监检单? new AjsonUnit(造监检单):null)
                .竣验日(bsd.getCompeAccpDate()).产品标准(bsd.getProductMeasure())
                .设计图号(bsd.getDesignPic()).总重量(String2Double(bsd.getEqpWeight()))
                .装项负责(bsd.getInstLeader()).装联电(bsd.getInstLkphone()).型试报告(bsd.getTestRepcod())
                .设计单位(null!=设计单位? new AjsonUnit(设计单位):null).设鉴单位(bsd.getDesignChkunt()).型试单位(null!=型试单位? new AjsonUnit(型试单位):null)
                .build();
        pam= pam.toBuilder().急救电(bsd.getEmergencyTel()).维保电(bsd.getMantPhone()).急救人(bsd.getEmergencyUserName())
                .联系电(bsd.getUsePhone()).联系人(bsd.getUseLkmen())
                .build();
        if(StringUtils.hasText(bsd.getEqpVart()))   eqpBld=eqpBld.vart(bsd.getEqpVart().substring(0,3));
        int icpa=0;
        Byte cpa=null;
        if(null!=bsd.getSafeLev())      icpa= String2Int(bsd.getSafeLev());
        else if(null!=bsd.getAcciType() && 0<String2Int(bsd.getAcciType()))   icpa=6 - String2Int(bsd.getAcciType());
        if(icpa>0 && icpa<=5)   cpa=(byte)icpa;
        //impt 旧检验平台变动了 0='国产', 1='部件进口' ,2='整机进口' 转换下编码：1='国产', 2='部件进口' ,3='整机进口'
        int impt=1;
        if(null != bsd.getImportType()) {    //监察平台编码 1='国产', 2='部件进口' ,3='整机进口'
            if("3".equals(bsd.getImportType()) || "整机进口".equals(bsd.getImportType()))   impt=3;
            else if("2".equals(bsd.getImportType()) || "部件进口".equals(bsd.getImportType()))   impt=2;
        }
        Float money= bsd.getEqpPrice();
        Boolean  cping= Boolean.valueOf(bsd.getIfIncping());
        eqpBld= eqpBld.reg(RegState_Enum.values()[String2Int(bsd.getEqpRegSta())]).ust(UseState_Enum.values()[String2Int(bsd.getEqpUseSta())])
                .uscd(null!=bsd.getUsestaChgDate()? bsd.getUsestaChgDate().toLocalDate() : null)
                .cerd(bsd.getRegDate())
                .plno(bsd.getEqpInnerCod()).money(money).cping(cping)
                .fno(bsd.getFactoryCod()).sno(bsd.getEqpStationCod()).rnam(bsd.getRegUserName()).move(Boolean.valueOf(bsd.getIsMoveeqp()))
                .vital("1".equals(bsd.getIfMajeqp()) || "是".equals(bsd.getIfMajeqp()) ).cpa(cpa).impt((byte)impt)
                .mkd(bsd.getMakeDate())
                .nxtd1(bsd.getNextIspDate1())
                .nxtd2(bsd.getNextIspDate2())
                .lpho(bsd.getUseMobile()).plat(bsd.getCatlicennum())
                .used(bsd.getFirstuseDate())
                .insd(bsd.getCompeAccpDate())       //jc.getInstCompDate()
                .expire(String2Date(bsd.getDesignUseOveryear()));
        if(null!=bsd.getRegUntId()) {
             eqpBld = eqpBld.regu(eqp.getSvu());
        }
        if(null!=bsd.getUseUntId())
            eqpBld = eqpBld.useu(getUnitfromOldUnitId(usjc,bsd.getUseUntId(),false));
        if(null!=bsd.getPropUntId())
            eqpBld = eqpBld.owner(getUnitfromOldUnitId(usjc,bsd.getPropUntId(),false));
        if(null!=bsd.getMantUntId())
            eqpBld = eqpBld.mtu(getUnitfromOldUnitId(usjc,bsd.getMantUntId(),false));
        Adminunit adminunit=adminunitRepository.findTopByAreacode(bsd.getEqpAreaCod());
        Village village=null;
        village=villageRepository.findTopByOldId(bsd.getBuildId());
        Double 纬度=null;   //latitude  -90<>90    必须约束,不合法数据存入ES报错！
        Double 经度=null;   //longitude  -180<>180
        if(null!=bsd.getEqpLat() && null!=bsd.getEqpLong()  && bsd.getEqpLat()>= -90 && bsd.getEqpLat()<= 90
                && bsd.getEqpLong()>= -180 && bsd.getEqpLong()<= 180 ){
            纬度=bsd.getEqpLat();
            经度=bsd.getEqpLong();
        }
        //监察平台：单位id竟然关联不同的很多表。
        eqpBld = eqpBld.makeu(getUnitfromOldUnitId(usjc, bsd.getMakeUntId())).insu(getUnitfromOldUnitId(usjc, bsd.getInstUntId()))
                .remu(getUnitfromOldUnitId(usjc, bsd.getAltUntId())).repu(getUnitfromOldUnitId(usjc, bsd.getOvhUntId()))
                .plat(bsd.getCatlicennum()).address(bsd.getEqpUseAddr()).lon(经度).lat(纬度)
                .plcls(mapFromEqpUsePlace(String2Int(bsd.getEqpUsePlace()))).dense(Boolean.valueOf(bsd.getIfPopulated()))
                .seimp(Boolean.valueOf(bsd.getIfMajplace()))
                .ad(adminunit).vlg(village).unqf1(Boolean.valueOf(bsd.getNoteligibleFalg1()))
                .unqf2(Boolean.valueOf(bsd.getNoteligibleFalg2()));
        //不止一个啊:plat?=>罐车牌号 VesselPrm."CARSIGN" ?or 厂车牌照 CarDrive.CATLICENNUM ||bsd.catlicennum 原来两处存储?
        //【删除字段】土建施单，固资值;土建验单,施工类别,施工日期;施工号,设计许号;合格证号; 都是仅存于监察临时表的？是施工告知单子,本平台不搞了。
        //【最近一次定期检验1,2】构建isp1 2? =外部报告new|Find?(简易4字段)；外部报告只有只简单的IspBase{却不是IspCold(没人关联的历史报告)},管道装置不需要同步。
        BusinessCat_Enum bsType;
        Isp isp1=null, isp2=null;
        if(!"8".equals(eqp.getType())) {        //管道=8,放在单元同步阶段做isp
            Isp.IspBuilder ispBuilder;
            if (StringUtils.hasText(bsd.getLastIspReport1())) {
                isp1 = iSPRepository.findTopByDevAndNo(eqp, bsd.getLastIspReport1());
                if (null == isp1) {
                    ispBuilder = new Isp().toBuilder().dev(eqp).no(bsd.getLastIspReport1());
                } else ispBuilder = isp1.toBuilder();
                Long optype = bsd.getLastIspopeType1();
                if (null != optype) {
                    int ioptype = optype.intValue();
                    if (usjc) bsType = BusinessCat_Enum.ofFjJC(ioptype);
                    else if (ioptype >= 600) {
                        bsType = BusinessCat_Enum.values()[ioptype - 600];
                        ispBuilder.entrust(true);
                    }
                    else bsType = BusinessCat_Enum.ofOldPT(ioptype);
                } else bsType = null;
                isp1 = ispBuilder.ispDate(bsd.getLastIspDate1())
                        .conclusion(bsd.getLastIspConclu1()).bsType(bsType).ispu(ispu).build();
                //isp1==isp2导致Eqp.save()报错！Multiple representations of the same entity [md.specialEqp.inspect.Isp#2516] are being merged.Detached: Managed:
                iSPRepository.save(isp1);
            }
            if (StringUtils.hasText(bsd.getLastIspReport2())) {
                isp2 = iSPRepository.findTopByDevAndNo(eqp, bsd.getLastIspReport2());
                if (null == isp2) {
                    ispBuilder = new Isp().toBuilder().dev(eqp).no(bsd.getLastIspReport2());
                } else ispBuilder = isp2.toBuilder();
                Long optype = bsd.getLastIspopeType2();
                if (null != optype) {
                    int ioptype = optype.intValue();
                    if(usjc)    bsType = BusinessCat_Enum.ofFjJC(ioptype);
                    else if (ioptype >= 600) {
                        bsType = BusinessCat_Enum.values()[ioptype - 600];
                        ispBuilder.entrust(true);    //委托的
                    }
                    else bsType = BusinessCat_Enum.ofOldPT(ioptype);
                } else bsType = null;
                isp2 = ispBuilder.ispDate(bsd.getLastIspDate2())
                        .conclusion(bsd.getLastIspConclu2()).bsType(bsType).ispu(ispu).build();
                //ispu不可以为空！ 前端抛出[md.specialEqp.inspect.Isp]  [jakarta.validation.groups.Default, ]\nList of constraint violations:
                iSPRepository.save(isp2);
                if (null != isp1 && isp2.getId().equals(isp1.getId()))
                    isp1 = null;   //同时new Isp()一次性作保存的，会报错Multiple representations being merged。
            }
            //[更多的]？ lastIspReport3 ， ?lastIspReport4    ?
        }
        String titl=bsd.getEqpName();
//        String titl= "8".equals(eqp.getType())? bsd.getPipeBoxName() : bsd.getEqpName();
        eqp=eqpBld.svp(Tool.toJSONString(svp)).pa(Tool.toJSONString(pam)).subv(bsd.getSubEqpVart()).cert(bsd.getEqpUsecertCod())
                .model(bsd.getEqpMod()).cnam(bsd.getRegUserName()).titl(titl).rcod(bsd.getEqpRegCod())
                .regd(bsd.getRegDate()).ocat(Boolean.valueOf(bsd.getInCag()))
                .cand(bsd.getRegLogoutDate()).isp1(isp1).isp2(isp2)
                .build();
        Division division=null, 检验部门=null;
        //使用单位的部门异常多，放在最后return。 优先采信旧检验平台,分支机构优先； 监察division数据更加不可信。分支机构本平台不能修改了。
        if(null!=eqp.getUseu()) {
            if(null!=bsd.getMgeDeptType()){
                if(2==bsd.getMgeDeptType() && null != bsd.getSecudeptId()){
                    UntSecudept untSecudept= untSecudeptRepository.findById(bsd.getSecudeptId()).orElse(null);
                    if(null!=untSecudept){      //判断两个Long类型是否相等，Long==Long不好使！
                        if(eqp.getUseu()!= getUnitfromOldUnitId(false,untSecudept.getUNT_ID()))
                            return new Tuple("分支机构UNT_ID不对y:"+untSecudept.getUNT_ID(), eqp);
                        //某停用设备的:单位是南平市建阳区鼎盛物业管理有限公司,但分支机构建阳区万商红商贸城 应属于 南平市建阳区宝泰房地产开发有限公司{错配!},监察平台没分支机构=null。使用单位改了，但是分支没改掉。
                        division = divisionRepository.findByUnitAndName(eqp.getUseu(), untSecudept.getName());
                    }else
                        return new Tuple("没分支机构:"+bsd.getSecudeptId(), eqp);
                }else if(1==bsd.getMgeDeptType() && null != bsd.getSafeDeptId()){
                    UntDept untDept=untDeptRepository.findById(bsd.getSafeDeptId()).orElse(null);
                    if(null!=untDept){
                        if(eqp.getUseu()!= getUnitfromOldUnitId(false,untDept.getUntId()))
                            return new Tuple("安全部门UNT_ID不对y:"+untDept.getUntId(), eqp);
                        division = divisionRepository.findByUnitAndName(eqp.getUseu(), untDept.getName());
                    }else
                        return new Tuple("没安全部门:"+bsd.getSafeDeptId(), eqp);
                }
            }
        }else {
            retRes = "使用单位空";   //单位变更后我方同步延迟了,滞后@ 【数据变化快】，单位已经注销=null可检验平台单位id没动;  使用单位=注销态
            if(null!=bsd.getUseUntId()) {
                retRes += " id=" + bsd.getUseUntId()+getFailOldUnitId映射(usjc,bsd.getUseUntId(),false);
                //【非正常数据】监察"报废"了当检验却是目录外在用。使用单位已经注销可是检验平台还能显示，检验平台分支机构和使用单位关联错误。
            }
        }
        if(null!=bsd.getEqpIspDept()) {
            HrDeptinfo  hrDeptinfo=hrDeptinfoRepository.findById(bsd.getEqpIspDept()).orElse(null);
            if(null!=hrDeptinfo && null!=hrDeptinfo.getDivision()) {
                检验部门 = divisionRepository.findById(hrDeptinfo.getDivision()).orElse(null);
            }
        }
        eqp= eqp.toBuilder().usud(division).ispud(检验部门).build();
        //设备等级 只针对 【4000起重 游乐 管道】 这3个种/类才有输入;
        if("4".equals(eqp.getType()) )    eqp.setLevel(bsd.getEqpLevel());
        return new Tuple(retRes, eqp);
    }

    /**采信那个数据源-Eqp结构化字段要以JC优先同步来源，svp+pa非结构化字段以JY优先采信同步来源。
     *输入：pjc，jcb是监察的技术参数和基础表；pjy，jyb是旧检验的技术参数和基础表；
     * 特定于某设备种类的参数 ;电梯不需要level字段; 新添加？字段'防沉降组合：'
     * 返回值特殊！2个字段的；【错误信息，更新后的Eqp】
     * */
    public Tuple fillElevator(Elevator eqp,OldDeviceSkel<ElvPara> ods) {
        String retRes ="";
        Elevator.ElevatorBuilder<?, ?>  eqpBld=eqp.toBuilder();
        ElvPara  pms= ods.getTechParam();
        if(null==pms)  return new Tuple("没参数表", eqp);    //才5条
        eqpBld =eqpBld.flo(pms.getElefloornumber()).hlf(pms.getEleheight())
                .vl(pms.getRunvelocity()).nnor("是".equals(pms.getIfUnnormal())).cpm(pms.getConscrtype()).tm(pms.getTracangtype())
                .mtm(pms.getElecType()).buff(pms.getBufferMode()).rtl(pms.getRatedload()).aap(pms.getIfAdddevice()).prot(pms.getCarProtectType())
                .doop(pms.getDoorOpenType()).limm(pms.getRestspeedtype()).opm(pms.getControlType()).lesc(pms.getSlidwayUseLeng())
                .wesc(pms.getNomiWidth());

            eqpBld =eqpBld.spec("1".equals(ods.getIfSpecEqp())).oldb("1".equals(pms.getIfOldbuildInst()))
                    .lbkd(ods.getLastBrakeTaskDate()).nbkd(ods.getNextBrakeTaskDate());
        String oldsvp= eqp.getSvp();
        ElevatorSvp svp=JSON.parseObject(oldsvp, ElevatorSvp.class);
        String oldpa= eqp.getPa();
        ElevatorPam pam=JSON.parseObject(oldpa, ElevatorPam.class);
        Float  绳直径=null;
        Boolean  是钢带=false;
        if(StringUtils.hasText(pms.getDragDia())){
            String txt=pms.getDragDia();        //特殊分解：是钢带？.绳直径 ： 钢带规格
            if(txt.indexOf('*')>=0 || txt.indexOf('×')>=0 || txt.indexOf('X')>=0)   是钢带=true;
            if(!是钢带)    绳直径=Tool.castFloat(txt);
        }
        svp= svp.toBuilder().电动机类(pms.getElecStyle()).屏号(pms.getContscrcode()).曳引号(pms.getTracangleafacnumber())
                .主机号(pms.getElecCod()).电机功率(pms.getElectropower()).电机转速(pms.getElecRev()).电梯门数(pms.getEledoornumber())
                .电梯站数(String2Short(pms.getElestadenumber())).顶层高度(pms.getTopheight()).对重轨距(Tool.castFloat(pms.getCoupOrbDist())).对重块数(pms.getCoupNum())
                .额定载人(pms.getRatedPeople()).轿厢轨距(pms.getCarOrbDist()).速比(pms.getVpropor()).拖动(pms.getDragMode()).曳引比(pms.getDragPropor())
                .轮节径(pms.getDragPitchDia()).绳数(pms.getDragNum()).上护型号(pms.getUpProtectType())
                .是钢带(是钢带).绳直径(绳直径).钢带规格(pms.getDragDia()).顶升形式(pms.getTopPatterns()).导轨型式(pms.getCounorbtype())
                .轿厢高(pms.getCarHigh()).轿厢宽(pms.getCarWidth())
                .轿厢深(pms.getCarDeep()).区域防爆(pms.getFbArealevel()).驱动方式(pms.getDrivApproach())
                .船梯("是".equals(pms.getIfShip())).汽车电梯("是".equals(pms.getIfCar()))
                .梯级宽度(pms.getRundlebreadth()).悬挂绳数(pms.getWireRopNum()).悬挂绳径(pms.getWireRopDia())
                .油缸数(pms.getCylinderNum()).油缸形式(pms.getCylinderStyle())
                .防爆标志(pms.getFbMachineflag()).倾斜角度(pms.getDipAngle()).泵功率(pms.getPumpPower())
                .build();
            //.公共交通("是".equals(pms.getIfPubTran()))
        pam= pam.toBuilder().上护编号(pms.getUpProtectCod()).钳型号(pms.getSafeclamtype()).钳编号(pms.getSafeclamnum()).底坑深度(pms.getBottomdepth())
                .补偿方式(pms.getCompentype()).对限速号(pms.getCoupLimitCod()).对限速型(pms.getCoupLimitType()).额定电流(pms.getRatedCurrent())
                .缓型号(pms.getBuffertype()).缓编号(pms.getBuffernumber()).缓厂家(pms.getBufferMakeUnt()).上限电速(pms.getCarUplimitEv())
                .上限机速(pms.getCarUplimitMv()).下限电速(pms.getCarDownlimitEv()).下限机速(pms.getCarDownlimitMv()).移护型(pms.getCarProtectType())
                .移护号(pms.getCarProtectCod()).锁型号(pms.getLockType())
                .限速器号(pms.getRestspleafacnumber()).限绳直径(pms.getLimitRopDia()).爆炸物质(pms.getFbSubstance())
                .上行额速(pms.getUpRatedV()).下额定速(pms.getDownRatedV()).限机械速(pms.getLimitMv()).泵编号(pms.getPumpCod())
                .泵流量(pms.getPumpFlux()).泵型号(pms.getPumpType()).泵转速(pms.getPumpSpeed()).液油型号(pms.getOilType()).防爆证号(pms.getFbHgcod())
                .build();
            pam= pam.toBuilder().层门型号(pms.getFloordoortype()).装修(pms.getCarDecorateSta())
                    .build();
            svp= svp.toBuilder().上护装置(pms.getUpProtectModeandtype())
                    .build();
        eqp=eqpBld.svp(Tool.toJSONString(svp)).pa(Tool.toJSONString(pam)).build();
        return new Tuple(retRes, eqp);
    }
    public Tuple fillVessel(Vessel eqp,OldDeviceSkel<VesPara> ods) {
        String retRes ="";
        VesPara  pms= ods.getTechParam();
        if(null==pms)  return new Tuple("没参数表", eqp);
        Vessel.VesselBuilder<?, ?>  eqpBld=eqp.toBuilder();
        String oldsvp= eqp.getSvp();
        VesselSvp svp=JSON.parseObject(oldsvp, VesselSvp.class);
        String oldpa= eqp.getPa();
        VesselPam pam=JSON.parseObject(oldpa, VesselPam.class);
        eqpBld =eqpBld.vol(pms.getContainervolume()).prs(pms.getDespre()).pnum(String2Short(pms.getCapablimitnum()))
                .highs(pms.getContainerheight()).weig(Tool.castFloat(pms.getTankcartowei())).rtlf(Tool.castFloat(pms.getLoadweig()))
                .fulw(Tool.castFloat(pms.getFullyloadwei())).mdi(pms.getTinamplmedi()).jakm(pms.getCovermedium())
                .form(pms.getCarstrform()).insul(pms.getTemppremode()).mont(pms.getInsform()).plat(pms.getCarsign());
        svp= svp.toBuilder().结构(pms.getMainstrform()).支座(pms.getBasestyle()).是换热("换热面积".equals(pms.getIfContainervolume()))
                .内径(pms.getConinndia()).许工作压(pms.getPermPress()).许工作温(pms.getPermTemp()).许工作介(pms.getPermMedium())
                .设计介(pms.getDesignMedium()).壳设压(pms.getShelldesignpress()).壳设温(pms.getShelldesigntemperatrue()).壳介(pms.getShellmedium())
                .管设压(Tool.castFloat(pms.getTubedesignpress())).管设温(pms.getTubedesigntemperatrue()).管介(pms.getTubemedium())
                .夹设压(pms.getCoverdesignpress()).夹设温(pms.getCoverdesigntemperatrue()).筒厚(pms.getCanisterply()).头厚(pms.getSealply())
                .衬厚(pms.getInnerply()).夹厚(pms.getCoverply()).人均容(pms.getAvgArea()).舱容限(pms.getCapablimit()).人均(pms.getCapablimitEvery())
                .有保温("1".equals(pms.getYnheatpreins()) || "保温层".equals(pms.getYnheatpreins())).舱设压(Tool.castFloat(pms.getDesignpress()))
                .加压式(pms.getPressmode()).规格(pms.getVesselMod()).车空重(Tool.castFloat(pms.getKzzl())).罐材内(pms.getInnjarmat())
                .罐材外(pms.getOutjarmat()).罐材头(pms.getEnvjarmat()).罐设压(Tool.castFloat(pms.getTindesipress())).底盘号(pms.getTanjarbatnum())
                .罐设温(Tool.castFloat(pms.getTindesitemp())).罐厚筒(Tool.castFloat(pms.getBamjarwalthi())).罐厚头(Tool.castFloat(pms.getEnvjarwalthi()))
                .罐厚外筒(pms.getBamjarwalthio()).罐厚外头(pms.getEnvjarwalthio()).底盘型(pms.getBatholithmodel()).时速(pms.getDesignvelocityloadsurface())
                .时速弯(pms.getDesignvelocitycorner()).罐容积(pms.getTincubage()).人孔位(pms.getTinholeposi()).罐外内径(Tool.castFloat(pms.getTinoutlineinner()))
                .罐外壁厚(Tool.castFloat(pms.getTinoutlineply())).罐外长(Tool.castFloat(pms.getTinoutlinelength())).盖厚(Tool.castFloat(pms.getTopPly()))
                .盖材料(pms.getTopMeterial()).盖形式(pms.getTopMod()).筒料球(pms.getBodyMeterial()).壁厚(pms.getWallThick())
                //.设规范(pms.getDesignLaw())
                .力类别(pms.getPresort()).封头型(pms.getSealtype()).是快开("是".equals(pms.getYnqopen())).监检式(pms.getInspectform())
                .制规范(pms.getManufacturecriterion())
                .build();
        pam= pam.toBuilder().充重(Tool.castFloat(pms.getLoadweight())).工作压(pms.getWorkPress()).工作温(pms.getWorkTemp())
                .工作介(pms.getWorkMedium()).筒料(pms.getSilomater()).封料(pms.getSealmater()).衬料(pms.getInnermater()).夹料(pms.getCovermater())
                .壳用压(pms.getShellusepress()).壳高压(Tool.castFloat(pms.getShelltoppress())).壳用温(pms.getShellusetemperatrue())
                .管用压(pms.getTubeusepress()).管高压(Tool.castFloat(pms.getTubetoppress())).管用温(pms.getTubetemperatrue())
                .夹用压(pms.getCoverusepress()).夹高压(Tool.castFloat(pms.getCovertoppress())).夹用温(pms.getCovertemperatrue())
                .筒腐裕(pms.getBodyRustGrade()).头腐裕(pms.getHeadRustGrade()).壳体重(pms.getChitinheft()).内件重(pms.getInnerheft())
                .舱高压(Tool.castFloat(pms.getTopworkpress())).舱用压(Tool.castFloat(pms.getUseworkpress())).空调式(pms.getAirconform())
                .照明(pms.getOxycablig()).测氧(pms.getMeaoxymod()).空调机(pms.getAirelemac()).表量程(pms.getPressurerange())
                .表精度(pms.getPressureapparprecision()).医疗登记(pms.getEnregisterno()).联合国号(pms.getJarundanno())
                .罐高压(Tool.castFloat(pms.getTiptoptem())).罐试压(Tool.castFloat(pms.getTanjarexapre())).功率(Tool.castFloat(pms.getEnginepower()))
                .侧稳定角(pms.getEmpsteaangel()).车形长(Tool.castFloat(pms.getWholecaroutlinelength())).车形宽(Tool.castFloat(pms.getWholecaroutlinewidth()))
                .车形高(Tool.castFloat(pms.getWholecaroutlineheigth())).轴荷前(pms.getFrfullaxisdist()).轴荷后(pms.getBafullaxisdist())
                .轴荷中(pms.getMifullaxisdist()).充系数(pms.getTinamplmodu()).充重量(Tool.castFloat(pms.getTinamplweig())).腐裕(pms.getTinerode())
                .保温料(pms.getTinheatpresmate()).热处(pms.getTinheattreafash()).耐试压(Tool.castFloat(pms.getTintestpress()))
                .气试压(pms.getTingastestpress()).铭牌位(pms.getNamplapos()).罐色(pms.getJarbodcor()).运行态(pms.getMotionSta())
                .安全(pms.getSecurityLev()).装卸位(pms.getLoaugropos()).装卸式(pms.getMediassemode()).危险介(pms.getDangerMedType())
                .build();
        eqp=(Vessel)eqpBld.svp(Tool.toJSONString(svp)).pa(Tool.toJSONString(pam)).build();
        return new Tuple(retRes, eqp);
    }
    public Tuple fillVessel常(Vessel eqp,OldDeviceSkel<NpvsPara> ods) {
        NpvsPara  pms= ods.getTechParam();   //监察没有R000单独技术表
        if(null==pms)   return new Tuple("没有技术参数", eqp);    //=17条
        Vessel.VesselBuilder<?, ?>  eqpBld=eqp.toBuilder();
        String oldsvp= eqp.getSvp();
        VesselSvp svp=JSON.parseObject(oldsvp, VesselSvp.class);
        String oldpa= eqp.getPa();
        VesselPam pam=JSON.parseObject(oldpa, VesselPam.class);
        eqpBld =eqpBld.vol(pms.getCubage()).rtlf(Tool.castFloat(pms.getRatedLoad())).plat(pms.getVehicNum());
        svp= svp.toBuilder().车辆类(pms.getCarType()).车架(pms.getCjNo()).发动机(pms.getEngineCod()).build();
        pam= pam.toBuilder().介质(pms.getInnerMedium()).铭牌(pms.getNameplateState()).运输证(pms.getSendCert())
                .外尺寸(pms.getShapeSize()).额定压(pms.getDesignPress()).价格(ods.getEqpPrice()).桶数(pms.getTubSum())
                .桶规格(pms.getTubType()).build();
        eqp=(Vessel)eqpBld.svp(Tool.toJSONString(svp)).pa(Tool.toJSONString(pam)).build();
        return new Tuple("", eqp);
    }
    public Tuple fillCrane(Crane eqp,OldDeviceSkel<CraPara> ods) {
        String retRes ="";
        CraPara  pms= ods.getTechParam();     //注销登记+迁出的设备：参数表变成空的。
        if(null==pms)    return new Tuple("没有参数表", eqp);
        Crane.CraneBuilder<?, ?>  eqpBld=eqp.toBuilder();
        String oldsvp= eqp.getSvp();
        CraneSvp svp=JSON.parseObject(oldsvp, CraneSvp.class);
        String oldpa= eqp.getPa();
        CranePam pam=JSON.parseObject(oldpa, CranePam.class);
        String occa=ods.getEqpUseOcca();
        Short  pnumf=String2Short(pms.getBernum());
        eqpBld =eqpBld.nnor("是".equals(pms.getIfUnnormal())).rtlf(castFloat(pms.getChaengloa())).vls(pms.getRatedspeed()).rvl(pms.getRunV())
                .mvl(pms.getLiftespeedmain()).cvl(pms.getLCarV()).scv(pms.getSCarV()).lmv(pms.getLanmovspe()).rtv(pms.getRotatesvelocity())
                .luff(pms.getAlterrangevelocity()).flo(String2Short(pms.getTcFloornum())).pnum(pnumf)
                .hlfm(castFloat(pms.getEleheightmain())).hlf(Tool.castFloat(pms.getEleheight())).rang(pms.getRange())
                .span(castFloat(pms.getSpan())).two("是".equals(pms.getIfTwoCab())).twoc("是".equals(pms.getIfTwoLcar())).grab("是".equals(pms.getIfGrabB()))
                .suck("是".equals(pms.getIfSuctorial())).cotr("是".equals(pms.getIfContainH())).walk("是".equals(pms.getIfXzs()))
                .mom(pms.getChaadvmom()).whole("是".equals(pms.getIfZjcc())).pcs(pms.getTcCarsize()).pcw(pms.getTcCarweight())
                .miot(Tool.castFloat(pms.getTcIoMaxtime())).opm(pms.getOperStytle()).luf(pms.getAlterrangemode()).jobl(pms.getWorkgrade())
                .highs(pms.getTcEqphigh()).part(pms.getUpBody()).occa(occa).metl("是".equals(pms.getIfMetallurgy()))
                .cap(pms.getMaxratedcarrymass()).auxh("是".equals(pms.getIfViceLoad())).wjib("是".equals(pms.getIfViceArm()));
            //非关键字段的:优先采信旧检验。
        svp= svp.toBuilder().臂构式(pms.getQmBjstyle()).臂类(pms.getQmBjtype()).变幅施(pms.getQmAlterrangemode()).节联接(pms.getQmBzjlstyle())
                .层站数(pms.getLayerstage()).搭载式(pms.getCarryMethod()).底架型(pms.getBasetype()).吊臂型(pms.getCranearmtype())
                .钩时额量(pms.getDgMaxratedcarrymass()).钩时幅(pms.getDgRange()).斗时额量(Tool.castFloat(pms.getZdMaxratedcarrymass()))
                .斗时幅(pms.getZdRange()).钩时幅(pms.getDgRange()).专时额量(Tool.castFloat(pms.getZyMaxratedcarrymass())).专时幅(pms.getZyRange())
                .主吊具(pms.getQmMainupType()).额起升速(pms.getLiftespeedvalue()).制动载荷(pms.getRatbraloa()).防爆(pms.getExSign())
                .防爆级(pms.getExplosiveLevel()).附装名(pms.getAuxiName()).附装品(pms.getAuxiType()).工半径(Tool.castFloat(pms.getWorkradius()))
                .工环境(pms.getWorkcondition()).轨长(pms.getRaillenth()).轨长桥(pms.getTrackLen()).轨距(Tool.castFloat(pms.getGauge()))
                .回转(pms.getQmHzstyle()).架桥承(pms.getJqjRatebearing()).架设式(pms.getSpanmode()).架设跨(pms.getSpabesdia()).监检式(pms.getInspectform())
                .门跨度(pms.getSpanLen()).门结构(pms.getQmMjstyle()).平衡重(pms.getCounterbalance()).副钩高(pms.getEleheightvice()).起升速(pms.getLiftespeed())
                .副钩速(pms.getLiftespeedvice()).覆力矩(pms.getUpsetmoment()).设型式(pms.getQmEqpType()).设规范(pms.getDesigncriterion())
                .伸展(pms.getSpanStruct()).生产率(pms.getOutput()).升降速(pms.getUpDownSpeed()).是监("是".equals(pms.getIfJhsy()))
                .有附装("是".equals(pms.getIfAuxi())).有监控("是".equals(pms.getIfMonitor())).专导梁("是".equals(pms.getIfSupport()))
                .塔顶型(pms.getTiptowertype()).塔身型(pms.getTowertype()).出入口(pms.getTcInoutsize()).桅杆(pms.getCantilCons()).悬长(pms.getArmLen())
                .悬2长(pms.getArmLen2()).悬跨度(Tool.castFloat(pms.getArmSpan()))
                .车方法(pms.getRunMethod()).支腿(pms.getSuppLeg()).造规(pms.getManufacturecriterion()).梁结构(pms.getQmMaingridStyle())
                .梁数(pms.getQmMaingridNum()).主悬件(pms.getQmMainupUnit()).主升机构(pms.getQmMainupunitType()).主体式(pms.getMainstrform())
                .主腿构(pms.getQmMainlegStyle()).自重(Tool.castFloat(pms.getEmptyWeight())).组装型(pms.getQmZztype()).最幅起(pms.getMaxMlift())
                .最工幅(pms.getMaxworkrange()).build();
        Float  附着f=Tool.castFloat(pms.getQmAuxiNumIsping());
        pam= pam.toBuilder().锁编号(pms.getSaflocnum()).锁型号(pms.getSafloctyp()).爆区(pms.getExplAreaPlot()).爆物(pms.getExplMattType())
                .承索数(pms.getQmCzsNum()).馈电式(pms.getQmCarmode()).导支跨度(pms.getSpanSupport()).吊具型(pms.getNacelletype())
                .检吊具(pms.getQmMainupTypeIsping()).笼行程(pms.getSuscagworjour()).顶升速(Tool.castFloat(pms.getTopupvelocity()))
                .动力系统(pms.getPowSystem()).副钩1重(Tool.castFloat(pms.getChaengloavice())).副钩2重(pms.getChaengloavice2())
                .电方轻(pms.getPowerSupp()).纵移速(pms.getPormovspe()).回转角(pms.getRotatesveangle()).基距(Tool.castFloat(pms.getBaseDistance()))
                .集前伸(pms.getContainLen()).监系号(pms.getMonitorFactorycod()).监系单(pms.getMonitorUnitName()).监系型(pms.getMonitorType())
                .副臂长(pms.getArmLen2Isping()).副钩倍(pms.getQmRatioViceIsping()).副额起(pms.getQmRatedcarrymassvice())
                .检跨度(pms.getSpanIsping()).架铰高(Tool.castFloat(pms.getQmArmHighIsping())).所在地(pms.getEqpUseAddrIsping())
                .主臂长(pms.getArmLen1Isping()).主钩倍(pms.getQmRatioMainIsping()).工作幅(Tool.castFloat(pms.getQmMaxworkrangeIsping()))
                .小车数(pms.getQmLiftcarNum()).起重臂(pms.getLiftArm()).总重(Tool.castFloat(pms.getCarrymasstotalwei())).取物(pms.getFetchset())
                .所爆级(pms.getFbArealevel()).标高差(pms.getDiffBetween()).提力矩(pms.getLiftedmmoment()).提绳径(Tool.castFloat(pms.getLifteropediam()))
                .停车式(pms.getTcStytle()).深度(pms.getDownDeep()).降速(pms.getDownSpeed()).驶速度(pms.getRunningspeed()).走范围(pms.getMovrange())
                .走速度(pms.getMovingvelocity()).移动型(pms.getQmMovetype()).易爆物(pms.getFbSubstance()).效半径(Tool.castFloat(pms.getEffRadius()))
                .效重量(pms.getExpcarrymass()).车运行时(pms.getRunTime()).轨道(pms.getRunTrack()).总功(Tool.castFloat(pms.getWholemachinetotalpower()))
                .钩1重(pms.getChaengloamain()).钩2重(pms.getChaengloamain2()).余冲程(pms.getCypStr()).自由高(pms.getFreeehigh())
                .独立高(Tool.castFloat(pms.getQmMaxhigh())).外伸距(Tool.castFloat(pms.getMaxOutlen())).最小幅监(pms.getMinMargins())
                .最小幅(pms.getMinworkrange()).附着(null!=附着f? 附着f.shortValue() : null).build();
        eqp=(Crane)eqpBld.svp(Tool.toJSONString(svp)).pa(Tool.toJSONString(pam)).build();
        return new Tuple(retRes, eqp);
    }
    //先把监察PcraneQzj提取升降机所有有用字段转为检验的IlifsParg。方便统一处理：监察平台的升降机技术参数数据有效字段太少;
    public Tuple fillCrane升降机(Crane eqp,OldDeviceSkel<LiftPara> ods) {
        String retRes ="";
//        if(null!=pjcCra)    pjc=lifterConvertParmFromJC(pjcCra);//监察升降机字段：转换成 检验的升降机字段; 监察没有独立表，检验有。
        LiftPara pms= ods.getTechParam();
        if(null==pms)  return new Tuple("没参数表", eqp);
        Crane.CraneBuilder<?, ?>  eqpBld=eqp.toBuilder();
        String oldsvp= eqp.getSvp();
        CraneSvp svp=JSON.parseObject(oldsvp, CraneSvp.class);
        String oldpa= eqp.getPa();
        CranePam pam=JSON.parseObject(oldpa, CranePam.class);
        //字段.level() 起重 在基础表当中就做了设置；
        Float  flof=Tool.castFloat(pms.getFloorNum());
        Float  nsf=Tool.castFloat(pms.getStationNum());
        String occa= ods.getEqpUseOcca();
        eqpBld =eqpBld.flo(null!=flof? flof.shortValue() : null).vls(pms.getRatedV()).rtlf(Tool.castFloat(pms.getRatedLoad()))
                .jobl(pms.getWorkLevl()).opm(pms.getControlType()).cpi(pms.getConScreenCod()).cpm(pms.getConScreenType())
                .mom(pms.getMaxMoment()).nnor("是".equals(pms.getIfUnnormal())).twoc("是".equals(pms.getIfTwoHois()))
                .hlf(Tool.castFloat(pms.getUpHigh())).tm(pms.getDragType()).tno(pms.getDragCod()).ns(null!=nsf? nsf.shortValue() : null)
                .occa(occa);
        svp= svp.toBuilder().节联接(pms.getConnectType()).层门型(pms.getDoorPattern()).层门式(pms.getDoorStytle()).传动(pms.getDrivApproach())
                .葫芦号(pms.getHoistCod()).葫芦型(pms.getHoistType()).电机号(pms.getElecCod()).电动机类(pms.getElecStyle()).电机型(pms.getElecType())
                .笼数(pms.getHoisNum()).对重块数(pms.getCoupNum()).对绳径(pms.getCoupRopDia()).额定载人(pms.getRatedPeople())
                .坠保护(pms.getFallProtect()).附属种(pms.getAuxiType()).工作式(pms.getOperStytle()).缓冲器(pms.getBufferMode())
                .限速器型(pms.getCarlimitVType()).门式(pms.getDoorCloseType()).门驱动(pms.getDoorDriveType()).门方向(pms.getDoorOpenDict())
                .伸展(pms.getSpanStruct()).绝缘("是".equals(pms.getIfInsulation()))
                 //.是防爆("是".equals(pms.getIfExplosive()))
                .有附装("是".equals(pms.getIfAuxi())).拖动(pms.getDragMode()).绳数(pms.getDragNum()).绳直径(Tool.castFloat(pms.getDragDia()))
                .最大幅(Tool.castFloat(pms.getMargins())).最工幅(pms.getTrackLen())
                .build();
        pam= pam.toBuilder().钳编号(pms.getSafeCod()).钳型号(pms.getSafeType()).电机功率(pms.getElecPower()).电机转速(pms.getElecRev())
                .笼行程(pms.getHoisTrip()).顶层高度(Tool.castFloat(pms.getTopHigh())).对重轨距(Tool.castFloat(pms.getCoupOrbDist()))
                .额定电流(pms.getRatedCurrent()).防爆标志(pms.getBlastsign()).坠安号(pms.getFallSaveCod()).坠安型(pms.getFallSaveType())
                .缓编号(pms.getBufferCod()).缓型号(pms.getBufferType()).缓厂家(pms.getBufferMakeUnt()).轨架高(Tool.castFloat(pms.getCounorbHeightIsping()))
                .笼数检(pms.getHoisNumIsping()).对块数检(pms.getCoupNumIsping()).附墙架(pms.getWallNumIsping())
                .轿厢轨距(Tool.castFloat(pms.getCarOrbDist())).下限电速(pms.getCarDownlimitEv()).下限机速(pms.getCarDownlimitMv())
                .限速器号(pms.getCarlimitVCod()).门数(Tool.castFloat(pms.getDoorNum())).环境(pms.getTaskCondition()).速比(pms.getVpropor())
                .提绳径(Tool.castFloat(pms.getUpRopDia())).限机械速(pms.getLimitMv()).限绳直径(Tool.castFloat(pms.getLimitRopDia()))
                .型试样(pms.getTestInfo()).曳引比(pms.getDragPropor()).轮节径(pms.getDragPitchDia()).用途(pms.getEqpUse()).自由高(pms.getFeedHigh())
                .独立高(Tool.castFloat(pms.getMostTop())).作业人(pms.getWorkMan())
                .build();
        eqp=(Crane)eqpBld.svp(Tool.toJSONString(svp)).pa(Tool.toJSONString(pam)).build();
        return new Tuple(retRes, eqp);
    }
    public Tuple fillBoiler(Boiler eqp,OldDeviceSkel<BoilPara> ods) {
        String retRes ="";
        BoilPara  pms= ods.getTechParam();
        if(null==pms)  return new Tuple("没参数表", eqp);
        Boiler.BoilerBuilder<?, ?>  eqpBld=eqp.toBuilder();
        String oldsvp= eqp.getSvp();
        BoilerSvp svp=JSON.parseObject(oldsvp, BoilerSvp.class);
        String oldpa= eqp.getPa();
        BoilerPam pam=JSON.parseObject(oldpa, BoilerPam.class);
        eqpBld =eqpBld.wall("是".equals(pms.getIfBoilWall())).power(Tool.castFloat(pms.getRatcon())).form(pms.getMainstrform())
                .fuel(pms.getBurningtype()).pres(pms.getDesworkpress()).bmod(pms.getBurnmode())
                .asemb("整组装".equals(pms.getFactoryType()));
        svp= svp.toBuilder().加热方式(pms.getHeatupmode()).水循环(pms.getWatercircletype()).工作介质(pms.getWorkMedium())
                .安装况(pms.getInstCon()).炉房型(pms.getStokeholdtype()).汽水分离(pms.getGaswaterapartmode()).用途(pms.getSepurp())
                .主体材料(pms.getMainmate()).过热调温(pms.getSteamtemptype()).介名(pms.getMediumName()).介牌号(pms.getMediumCod())
                .介许温(Tool.castFloat(pms.getMediumAllowTemp())).予热器构(pms.getWarmupstrform()).燃器布置(pms.getBurntlaytype())
                .烧设备(pms.getBurequ()).设标准(pms.getDessta()).设出口温(pms.getDesexptem()).设出口压(pms.getDesexpstr()).设规范(pms.getDesigncriterion())
                .设挥发(pms.getBurntvolati()).设热效(pms.getDesithereffi()).设低热(Tool.castFloat(pms.getLowburnvalue())).设低热位(pms.getLowburnunit())
                .状态(pms.getUsestates()).水处式(pms.getWaterdealtype()).水处设型(pms.getWaterClMod()).制水能力(pms.getWoEqpPress())
                .水处造单(pms.getWaterEqpMakeUntName()).水源种(pms.getFousor()).烟尘式(pms.getSootavoidmode()).许用压(pms.getUsestr())
                .有载牌号(pms.getOrghcarbno()).许工温(pms.getAllwortem()).再热调温(pms.getResteamtemptype()).蒸汽用途(pms.getSteamfor())
                .制造范(pms.getManufacturecriterion()).build();
        pam= pam.toBuilder().饱和温度(Tool.castFloat(pms.getSattem())).补给水(pms.getAddwaterdealtype()).出口温(pms.getExpwortem())
                .出口压(pms.getExpworstr()).出热量(pms.getOutHot()).出水温度(Tool.castFloat(pms.getComwattem())).出渣(pms.getDrosstype())
                .除氧(pms.getDeoxidizemode()).司炉数(pms.getBoilernum()).电站情况(pms.getOthpara()).额定出力(pms.getHeatPow())
                .给水温(pms.getFeedwatertem()).给水压(pms.getFeewatstr()).工作温度(pms.getWorkTemp()).筒工作压(pms.getSiloworkpress())
                .过热温(pms.getSteamexporttem()).过热压(pms.getSteamexportpress()).回水温(pms.getBacwattem()).介出温(pms.getMediexporttemp())
                .介验日(pms.getMediumAssayDate()).试验介质(pms.getCompressTryMedium()).压验日(pms.getCompressTryDate())
                .试压力(Tool.castFloat(pms.getStrexmstr())).再热出温(Tool.castFloat(pms.getResteamexporttem()))
                .能效测标(pms.getNxcod()).能效评价(pms.getEffEval()).省煤构(pms.getPinchstrform()).蒸发量(Tool.castFloat(pms.getWorkPower()))
                .使用年限(Tool.castFloat(pms.getWorkAge())).有过热器("是".equals(pms.getSteamif()) || "有".equals(pms.getSteamif()))
                .使用压力(pms.getWorkPress()).受热布置(pms.getBeheatMachType()).水处模式(pms.getWaterYxms())
//.水压试日(pms.getWatPrsDate()).水压试力(pms.getWatPrs()).液验介(pms.getHydrDressTryMedium()).液验日(pms.getHydrDressTryDate()).液验压(pms.getHydrDressTryPress())
                .水油联话(pms.getUserWaLinkphone()).水油联人(pms.getUserWaLinkman()).水员数(pms.getWaterdealnum())
                .再热入温(Tool.castFloat(pms.getResteamimporttem())).再热出压(Tool.castFloat(pms.getResteamexportpress()))
                .再热入压(Tool.castFloat(pms.getResteamimportpress())).再汽流(Tool.castFloat(pms.getReheatflux()))
                .直启动流(Tool.castFloat(pms.getDireboilerstartflux())).直启动压(Tool.castFloat(pms.getDireboilerstartpress()))
                .最连蒸(pms.getMostvapovalue()).build();
        eqp=(Boiler)eqpBld.svp(Tool.toJSONString(svp)).pa(Tool.toJSONString(pam)).build();
        return new Tuple(retRes, eqp);
    }
    public Tuple fillFactoryVehicle(FactoryVehicle eqp,OldDeviceSkel<CarPara> ods) {
        String retRes ="";
        CarPara  pms= ods.getTechParam();
        if(null==pms)  return new Tuple("没参数表", eqp);
        FactoryVehicle.FactoryVehicleBuilder<?, ?>  eqpBld=eqp.toBuilder();
        String oldsvp= eqp.getSvp();
        FactoryVehicleSvp svp=JSON.parseObject(oldsvp, FactoryVehicleSvp.class);
        String oldpa= eqp.getPa();
        FactoryVehiclePam pam=JSON.parseObject(oldpa, FactoryVehiclePam.class);
        eqpBld =eqpBld.pow(pms.getDynamicmode()).rtlf(castFloat(pms.getRatedloadweig())).mtm(pms.getEnginemodel());
        if(!StringUtils.hasText(eqp.getPlat()))   eqpBld.plat(pms.getCatlicennum());
        svp= svp.toBuilder().牌型(pms.getBrandmodel()).防爆级(pms.getExplosiveLevel()).车类型(pms.getCartype()).厢数(pms.getCarNum())
                .传动(pms.getDrivApproach()).底盘号(pms.getBatnum()).电机号(pms.getMotornum()).机编号(pms.getEngnum()).机功率(pms.getEnginePower())
                .机转速(pms.getEngineV()).后轮距(pms.getRearTrack()).驾员(pms.getCabquota()).升最高(castFloat(pms.getMaxlifheightWithoutLoad()))
                .前轮距(pms.getFrontGauge()).燃料(pms.getBurkin()).电压(pms.getSystemVoltage())
                .行装置(pms.getCarriDevic()).最坡度(pms.getMaxDriveSlope()).时速(pms.getTiptopmph())
                .build();
        pam= pam.toBuilder().环境(pms.getVehicUseEnv()).用区域(pms.getCarUseArea()).车空重(pms.getEmptyWeight()).胎型(pms.getTyreType())
                .厢座位(pms.getCarriageSeatsNum()).头座位(pms.getFrontSeatsNum()).引力(pms.getDragPower()).驱动(pms.getDriver())
                .油类(pms.getFueltype()).场防爆级(pms.getFbArealevel()).区域型(pms.getUseArea()).颜色(pms.getColor())
                .有拖("有".equals(pms.getTrailer())).速度(pms.getRunspeed()).载心距(pms.getLoadCenter())
                .build();
        eqp=(FactoryVehicle)eqpBld.svp(Tool.toJSONString(svp)).pa(Tool.toJSONString(pam)).build();
        return new Tuple(retRes, eqp);
    }
    public Tuple fillAmusement(Amusement eqp,OldDeviceSkel<AmusPara> ods) {
        String retRes ="";
        AmusPara  pms= ods.getTechParam();
        if(null==pms)  return new Tuple("没参数表", eqp);
        Amusement.AmusementBuilder<?, ?>  eqpBld=eqp.toBuilder();
        String oldsvp= eqp.getSvp();
        AmusementSvp svp=JSON.parseObject(oldsvp, AmusementSvp.class);
        String oldpa= eqp.getPa();
        AmusementPam pam=JSON.parseObject(oldpa, AmusementPam.class);
        String level=null;
        if(StringUtils.hasText(ods.getEqpLevel())){
            if("A".equals(ods.getEqpLevel()))      level="A级";
            else if("B".equals(ods.getEqpLevel()))     level="B级";
            else if("C".equals(ods.getEqpLevel()))     level="C级";
        }
        eqpBld =eqpBld.level(level).angl(pms.getSwingangle()).leng(castFloat(pms.getLength())).pnum(pms.getRatedpassengernum())
                .vl(pms.getRatedvelocity()).sdia(pms.getTurningdiameter()).grad(pms.getGrade()).mbig("是".equals(pms.getIfShift()))
                .high(castFloat(pms.getHeight())).hlf(Tool.castFloat(pms.getMovHigh()));
        svp= svp.toBuilder().半径(pms.getRadii()).蹦极(pms.getJumpType()).场面积(Tool.castFloat(pms.getCarageArea())).电压(pms.getPressure())
                .额载荷(pms.getRatedload()).副速度(pms.getSubvelocity()).绳直径(pms.getWireropedia()).高差(pms.getHeigdiff()).轨长(pms.getRaiwaylen())
                .轨高(pms.getTrackheigh()).轨数(pms.getRaiwaynum()).轨距(pms.getGauge()).提送(pms.getSlidewayMachine()).道种类(pms.getSlidewayType())
                .道材索根(pms.getSlidewayStuff()).索数(pms.getSlideNum()).回收式(pms.getBackType()).驱动式(pms.getDriveform())
                .设备高(Tool.castFloat(pms.getEqpHigh())).深度(pms.getDepth()).小蹦("是".equals(pms.getIfMinJump()))
                .池型(pms.getPoolType()).池深(pms.getCarniewterdeep()).舱高(pms.getSeatheight())
                .舱数(String2Short(pms.getSeacabnum())).build();
        pam= pam.toBuilder().车数(pms.getCarShpNum()).电动机转速(pms.getEleMotoRev()).副功率(pms.getSubpower()).轨距长(pms.getGaugelength())
                .回收装(pms.getRecovery()).主功率(castFloat(pms.getDrivemainpower())).滑梯高(pms.getWaterslideheight()).平距(Tool.castFloat(pms.getLineWidth()))
                .线速度(pms.getLinevelocity()).圆速度(pms.getCirspe()).直半径(pms.getDiarad()).build();
        eqp=(Amusement)eqpBld.svp(Tool.toJSONString(svp)).pa(Tool.toJSONString(pam)).build();
        return new Tuple(retRes, eqp);
    }
    public Tuple fillPipeline(Pipeline eqp,OldDeviceSkel<PpinPara> ods) {
        String retRes ="";
        PpinPara  pms= ods.getTechParam();
        Pipeline.PipelineBuilder<?, ?>  eqpBld=eqp.toBuilder();
        String oldsvp= eqp.getSvp();
        PipelineSvp svp=JSON.parseObject(oldsvp, PipelineSvp.class);
        String oldpa= eqp.getPa();
        PipelinePam pam=JSON.parseObject(oldpa, PipelinePam.class);
        if(null==pms) {
            eqp=(Pipeline)eqpBld.build();
            return new Tuple("没装置参数表", eqp);    //但可以有单元
        }
        if(!StringUtils.hasText(eqp.getTitl())) {    //3个地方来源
            if(StringUtils.hasText(pms.getBoxName()))     eqpBld.titl(pms.getBoxName());
            else  eqpBld.titl(ods.getEqpName());
        }
        eqpBld =eqpBld.level(pms.getPipelineLevel()).matr(pms.getPipelineMedium()).mdi(pms.getWorkMedium()).temp(pms.getDesignTemp())
                .prs(pms.getDesignPress());
        String  设备名=ods.getEqpName();   //主表EQP_NAME字段
        svp= svp.toBuilder().保温式(pms.getAdiabaticType()).腐材料(pms.getEmbalmment()).腐裕量(pms.getRotAmount())
                .工作温(pms.getWorkTemp()).工作压(pms.getWorkPress()).公壁厚(pms.getNominalPly()).公直径(pms.getNominalDia()).衬厚(pms.getInnerPly())
                .起点(pms.getStartPlace()).止点(pms.getEndPlace()).管道设备名(设备名).最高温(pms.getTopWorkTemp())
                .最高压(pms.getTopWorkPress()).附属设(ods.getIfFsEqp()).build();
        pam= pam.toBuilder().保装数(pms.getSafeMecNum()).腐施单(pms.getAntisepsisUnt()).根数(pms.getPipeNum())
                    //.安全级(pms.getSafeLevel()).监检号(pms.getWarrantCod())
                .总长(pms.getLength()).敷设(pms.getLayMode()).管规(pms.getPipelineSpec()).管厚(pms.getPipelinePly()).管材牌(pms.getPipelineDatumSign())
                .焊口数(pms.getHkNum()).绝热材(pms.getAdiabaticMedium()).绝热厚(pms.getAdiabaticPly()).衬料(pms.getInnerMedium())
                .实用时(pms.getUseTime()).试压(pms.getTryPress()).输送介(pms.getSendMedium())
                .探伤比(pms.getFalwRadio()).保温(pms.getIfSavetemp()).build();
        eqp=(Pipeline)eqpBld.svp(Tool.toJSONString(svp)).pa(Tool.toJSONString(pam)).build();
        return new Tuple(retRes, eqp);
    }
    //分解，避免事务太长时间
    public Boolean syncFromLegacy_AU管道单元(JsliceMang jobm, String arg) {
        //没添加joinTransaction就不会保存数据库的。
        if(!emFjtj.isJoinedToTransaction())      emFjtj.joinTransaction();
        int pagesize=200;
        log.info("syncEqpFromLegacy_AK单元: 开始 offset={}",jobm.getOffs());
        InfRespond<PipeLineUnit>  recv=null;
        if(jobm.getOffs() >jobm.getTotl()) {
            jobm.setDesc("无法前进offset超过totl");    //默认jobm.getLimt()==1 数据库也必须配置=1
            return false;
        }
        int page=jobm.getOffs();    //实体要配置limt:=1; offs=1开始的;  totl>=sum/pagesize;
        recv=zhjyInf.getPipelineParam(page,pagesize);
        List<PipeLineUnit> allrs=recv.getRows();
        int countall=recv.getRows().size();
        int lopct=0;
        List<PipeLineUnit> batch=new ArrayList<>();
        log.info("syncEqpFromLegacy_AK: 接口完count={}",countall);
        for(PipeLineUnit one: allrs)
        {
            batch.add(one);
            lopct++;
            if(lopct>20) {
                pipeLineUnitRepository.saveAll(batch);
                lopct=0;
                batch.clear();
            }
        }
        pipeLineUnitRepository.saveAll(batch);
        log.info("syncEqpFromLegacy_单元 完成！offs={},条数{}提交数据库",jobm.getOffs(), countall);
        jobm.setOffs(jobm.getOffs()+1);
        if(countall < pagesize) {
            jobm.setDesc("无法前进offset");
            return false;
        }
        return true;
    }
    /**管道单元同步： 没考虑监察的，未处理旧遗留的数据被删除掉的情形。
     * */
    public Triple syncPipeDevice(PipeLineUnit eqp,String channel) {
/*        int jcSize= null!=jc? jc.size() :0;
        int jySize= null!=jy? jy.size() :0;
        if(jcSize<=0 && jySize<=0)  return new Triple("没单元", null, null);   //Tuple("没单元", eqp);    //11815条
        if(jcSize+jySize>1000)      log.info("单元数{},{}", jcSize,jySize);
        Map<String, DyguanDao>  mregc= new HashMap<>();     //监察的;有登记码的：EQP_UNT_REGCOD 做唯一性表示符
        Map<String, DyguanDao>  mregy= new HashMap<>();     //不是线程安全的 synchronize;
        Map<String, DyguanDao>  murc= new HashMap<>();    //EQP_CODE, START_PLACE, END_PLACE, BOX_NAME+rno ==唯一性
        Map<String, DyguanDao>  mury= new HashMap<>();      //旧检验平台:最多的,包含无登记代码的；
        Map<String, PipingUnit>  mcell= new HashMap<>();     //本平台现成的。

        // pipingUnitRepository.delete(et);            String plukey=mapHashKey(et);  mcell.put(plukey, et);转为Hash避免重复的Key
        if (null == myu)    myu = new PipingUnit();

//            myu= fillPipeUnitPrm(myu,jcu,entry.getValue(),pipingContext);
            myu.setPipe(eqp);
            batch.add(myu);
            //eqp.getCells().add(myu);
        pipingUnitRepository.saveAll(batch);
        int umFailSum=0;
        StringBuilder  sbuilder = new StringBuilder(512);
        sbuilder.append("没找到单位:");
        Iterator<Map.Entry<String, Unit>>  ctxuit= pipingContext.getMunit().entrySet().iterator();
        while (ctxuit.hasNext()) {
            Map.Entry<String, Unit>  entry = ctxuit.next();
            if(null==entry.getValue() && StringUtils.hasText(entry.getKey()) ) {
                sbuilder.append(entry.getKey()).append(';');
                umFailSum++;
            }
        }
        if(umFailSum>0)  return new Tuple(sbuilder.toString(), eqp);*/
        return new Triple("", null, null);  //Tuple("", eqp);
    }
}
